// Copyright 2007-2013 metaio GmbH. All rights reserved.
package com.metaio.Example;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import com.metaio.sdk.ARViewActivity;
import com.metaio.sdk.MetaioDebug;
import com.metaio.sdk.SensorsComponentAndroid;
import com.metaio.sdk.jni.IGeometry;
import com.metaio.sdk.jni.IMetaioSDKCallback;
import com.metaio.sdk.jni.IRadar;
import com.metaio.sdk.jni.LLACoordinate;
import com.metaio.tools.io.AssetsManager;

public class Tutorial5 extends ARViewActivity implements SensorsComponentAndroid.Callback 
{
	/**
	 * Geometries
	 */
	private IGeometry mGeometrySouth;
	//private IGeometry mGeometryWest;
	private IGeometry mGeometryNorth;
	private IGeometry mGeometryEast;
	private ArrayList<IGeometry> locations;
	private JSONArray jsonArray;
	private JSONObject json;
	private IRadar mRadar;
	public Spinner spin;
	private String mCategory;
	private double userDistance;
	private DrawerLayout mDrawerLayout;
	private ListView mDrawerList;
	private ActionBarDrawerToggle mDrawerToggle;
	private CharSequence mDrawerTitle;
	private CharSequence mTitle;
	private String[] mPlanetTitles;
	/**
	 * Offset from current location
	 */
	//private static final double OFFSET = 0.00002;

	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		json = new JSONObject();
		jsonArray = new JSONArray();
		//locations= new IGeometry[10];
		// Set GPS tracking configuration
		// The GPS tracking configuration must be set on user-interface thread
		boolean result = metaioSDK.setTrackingConfiguration("GPS");  
		MetaioDebug.log("Tracking data loaded: " + result); 
		mTitle = mDrawerTitle = getTitle();
		mPlanetTitles = getResources().getStringArray(R.array.planets_array);
		mDrawerLayout = (DrawerLayout) mGUIView.findViewById(R.id.drawer_layout);
		mDrawerList = (ListView) mGUIView.findViewById(R.id.left_drawer);
		locations = new ArrayList<IGeometry>();
		// set a custom shadow that overlays the main content when the drawer opens
		mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
		// set up the drawer's list view with items and click listener
		mDrawerList.setAdapter(new ArrayAdapter<String>(this,
				R.layout.drawer_listview_item, mPlanetTitles));
		mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

		// enable ActionBar app icon to behave as action to toggle nav drawer
		getActionBar().setDisplayHomeAsUpEnabled(true);
		getActionBar().setHomeButtonEnabled(true);

		// ActionBarDrawerToggle ties together the the proper interactions
		// between the sliding drawer and the action bar app icon
		mDrawerToggle = new ActionBarDrawerToggle(
				this,                  /* host Activity */
				mDrawerLayout,         /* DrawerLayout object */
				R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
				R.string.drawer_open,  /* "open drawer" description for accessibility */
				R.string.drawer_close  /* "close drawer" description for accessibility */
				) {
			public void onDrawerClosed(View view) {
				getActionBar().setTitle(mTitle);
				invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
			}

			public void onDrawerOpened(View drawerView) {
				getActionBar().setTitle(mDrawerTitle);
				invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
			}
		};
		mDrawerLayout.setDrawerListener(mDrawerToggle);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main, menu);
		return super.onCreateOptionsMenu(menu);
	}

	/* Called whenever we call invalidateOptionsMenu() */
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// If the nav drawer is open, hide action items related to the content view
		boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
		menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// The action bar home/up action should open or close the drawer.
		// ActionBarDrawerToggle will take care of this.
		if (mDrawerToggle.onOptionsItemSelected(item)) {
			return true;
		}
		// Handle action buttons
		switch(item.getItemId()) {
		case R.id.action_websearch:
			// create intent to perform web search for this planet
			Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
			intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
			// catch event that there's no activity to handle intent
			if (intent.resolveActivity(getPackageManager()) != null) {
				startActivity(intent);
			} else {
				Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
			}
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	/* The click listner for ListView in the navigation drawer */
	private class DrawerItemClickListener implements ListView.OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			try {
				selectItem(position);
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void selectItem(int position) throws JSONException {
		// update the main content by replacing fragments
		mCategory = mPlanetTitles[position];
		Log.d("RETURN", mCategory);
		// update selected item and title, then close the drawer
		mDrawerList.setItemChecked(position, true);
		setTitle(mPlanetTitles[position]);
		mDrawerLayout.closeDrawer(mDrawerList);
		//new SendData().execute();
		new SendData().execute();
	}

	class SendData extends AsyncTask<String, String, String>{
		ProgressDialog pd;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			pd = new ProgressDialog(mGUIView.getContext());
			pd.setTitle("Processing...");
			pd.setMessage("Please wait.");
			pd.setCancelable(false);
			pd.setIndeterminate(true);
			pd.show();
		}

		@Override
		protected String doInBackground(String... args) {
			// TODO Auto-generated method stub
			String line = "";
			try {			
				// Building Parameters

				//List<NameValuePair> params = new ArrayList<NameValuePair>();

				//params.add(new BasicNameValuePair("X", setUserX.getText().toString()));
				//params.add(new BasicNameValuePair("Y", setUserY.getText().toString()));
				//params.add(new BasicNameValuePair("Bearing", setBearing.getText().toString()));
				//jsonArray = new JSONArray();
				HttpClient httpclient = new DefaultHttpClient();
				String URL = "http://192.168.0.11/Project/makepoints.php?" +
						"X="+mSensors.getLocation().getLatitude()+"&Y="+mSensors.getLocation().getLongitude()+"&Category=" +
						mCategory+"&Distance=500";
				HttpPost httppost = new HttpPost(URL);

				//List<NameValuePair> nvp = new ArrayList<NameValuePair>(2);    
				//nvp.add(new BasicNameValuePair("json", json.toString()));
				//httppost.setHeader("Content-type", "application/json");  
				//httppost.setEntity(new UrlEncodedFormEntity(params));
				//locations = new IGeometry[10];
				HttpResponse response = httpclient.execute(httppost); 
				HttpEntity rslts = response.getEntity();
				InputStream is = rslts.getContent();
				BufferedReader reader = new BufferedReader(new InputStreamReader(
						is, "iso-8859-1"), 8);
				StringBuilder sb = new StringBuilder();
				//String line = null;
				while ((line = reader.readLine()) != null) {
					sb.append(line + "\n");
					Log.d("RETURN", "Line: "+line);
				}
				//System.out.println("Line: "+line);
				is.close();
				json = new JSONObject(sb.toString());
				jsonArray = json.getJSONArray("locations");
				updateGeometriesLocation(mSensors.getLocation());
				return line;
				//System.out.println("Results: "+rslts.toString());

			}catch(Exception e){
				e.printStackTrace();

			}


			return line;
		}
		protected void onPostExecute(String result) {
			super.onPostExecute(result);

			if (pd!=null) {
				pd.dismiss();

			}
		}

	}

	@Override
	public void setTitle(CharSequence title) {
		mTitle = title;
		getActionBar().setTitle(mTitle);
	}

	/**
	 * When using the ActionBarDrawerToggle, you must call it during
	 * onPostCreate() and onConfigurationChanged()...
	 */

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		// Sync the toggle state after onRestoreInstanceState has occurred.
		mDrawerToggle.syncState();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		// Pass any configuration change to the drawer toggls
		mDrawerToggle.onConfigurationChanged(newConfig);
	}


	@Override
	protected void onPause() 
	{
		super.onPause();

		// remove callback
		if (mSensors != null)
		{
			mSensors.registerCallback(null);
			//	mSensorsManager.pause();
		}


	}

	@Override
	protected void onResume() 
	{
		super.onResume();

		// Register callback to receive sensor updates
		if (mSensors != null)
		{
			mSensors.registerCallback(this);
			//mSensorsManager.resume();
		}

	}

	@Override
	public void onLocationSensorChanged(LLACoordinate location)
	{
		MetaioDebug.log("Location changed: "+location);
		try {
			updateGeometriesLocation(location);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	public void onButtonClick(View v)
	{
		finish();
	}

	@Override
	protected int getGUILayout() 
	{

		return R.layout.tutorial5; //was tutorial5
	}

	@Override
	protected IMetaioSDKCallback getMetaioSDKCallbackHandler() 
	{
		return null;
	}

	@Override
	protected void loadContents() 
	{


		try
		{ 
			String filepath = AssetsManager.getAssetPath("Tutorial5/Assets5/POI_bg.png");
			if(filepath != null){
				mRadar = metaioSDK.createRadar();
				for (int i = 0; i < 50; i++) {

					//JSONObject x = jsonArray.getJSONObject(i);
					//String name = x.getString("Name");
					locations.add(i, metaioSDK.loadImageBillboard(createBillboardTexture("POI")));
					Log.d("CHECK", "checking: "+locations.get(i).toString());

				}
			}





			/*
			filepath = AssetsManager.getAssetPath("Tutorial5/Assets5/metaioman.md2");
			if (filepath != null) 
			{
				// West
				mGeometryWest = metaioSDK.createGeometry(filepath);
				if (mGeometryWest != null)
				{
					mGeometryWest.startAnimation("idle", true);
					mGeometryWest.setScale(new Vector3d(4f,4f,4f));
				}

			}
			 */

			// create radar
			updateGeometriesLocation(mSensors.getLocation());
			
			
			mRadar.setBackgroundTexture(AssetsManager.getAssetPath("Tutorial5/Assets5/radar.png"));
			mRadar.setObjectsDefaultTexture(AssetsManager.getAssetPath("Tutorial5/Assets5/yellow.png"));
			mRadar.setRelativeToScreen(IGeometry.ANCHOR_TL);
			metaioSDK.setLLAObjectRenderingLimits(100, 800);

			// add geometries to the radar
			//			brdgrp.addBillboard(mGeometryEast);
			//		brdgrp.addBillboard(mGeometrySouth);
			//	brdgrp.addBillboard(mGeometryNorth);
			//for (IGeometry i : locations) {
			//	mRadar.add(i);
			//}
			//mRadar.add(mGeometryNorth);
			//mRadar.add(mGeometrySouth);
			//mRadar.add(mGeometryEast);
		}catch(Exception s){

		}

	}

	private String createBillboardTexture(String billBoardTitle)
	{
		try
		{
			final String texturepath = getCacheDir() + "/" + billBoardTitle + ".png";
			Paint mPaint = new Paint();

			// Load background image (256x128), and make a mutable copy
			Bitmap billboard = null;

			//reading billboard background
			String filepath = AssetsManager.getAssetPath("Tutorial5/Assets5/POI_bg.png");
			Bitmap mBackgroundImage = BitmapFactory.decodeFile(filepath);

			billboard = mBackgroundImage.copy(Bitmap.Config.ARGB_8888, true);


			Canvas c = new Canvas(billboard);


			mPaint.setColor(Color.WHITE);
			mPaint.setTextSize(20);
			mPaint.setTypeface(Typeface.DEFAULT);

			float y = 40;
			float x = 30;

			// Draw POI name
			if (billBoardTitle.length() > 0)
			{
				String n = billBoardTitle.trim();

				final int maxWidth = 200;

				int i = mPaint.breakText(n, true, maxWidth, null);
				c.drawText(n.substring(0, i), 2, y, mPaint);

				// Draw second line if valid
				if (i < n.length())
				{
					n = n.substring(i);
					y += 20;
					i = mPaint.breakText(n, true, maxWidth, null);

					if (i < n.length())
					{
						i = mPaint.breakText(n, true, maxWidth - 20, null);
						c.drawText(n.substring(0, i) + "...", x, y, mPaint);
					} else
					{
						c.drawText(n.substring(0, i), x, y, mPaint);
					}
				}

			}


			// writing file
			try
			{
				FileOutputStream out = new FileOutputStream(texturepath);
				billboard.compress(Bitmap.CompressFormat.PNG, 90, out);
				MetaioDebug.log("Texture file is saved to "+texturepath);
				return texturepath;
			} catch (Exception e) {
				MetaioDebug.log("Failed to save texture file");
				e.printStackTrace();
			}

			billboard.recycle();
			billboard = null;

		} catch (Exception e)
		{
			MetaioDebug.log("Error creating billboard texture: " + e.getMessage());
			MetaioDebug.printStackTrace(Log.DEBUG, e);
			return null;
		}
		return null;
	}



	private void updateGeometriesLocation(LLACoordinate location) throws JSONException
	{
		if(jsonArray.length() == 0){
			for (int i = 0; i < locations.size(); i++) {
				locations.get(i).setVisible(false);
			}
		}
		//mRadar = metaioSDK.createRadar();
		Log.d("RETURN", "size: "+jsonArray.length());
		if(jsonArray.length() > 0){
			
			//locations.clear();
			
			mSurfaceView.queueEvent(new Runnable()
			{
				@Override
				public void run() 
				{
					for (int i = 0; i < jsonArray.length(); i++) {
						try {	
							mRadar.remove(locations.get(i));
							locations.get(i).setVisible(false);							
							float lng = Float.parseFloat(jsonArray.getJSONObject(i).getString("Long"));
							float lat = Float.parseFloat(jsonArray.getJSONObject(i).getString("Lat"));
							LLACoordinate tmp = new LLACoordinate(lng, lat,0, 0);
							String name = jsonArray.getJSONObject(i).getString("Name");
							IGeometry g = metaioSDK.loadImageBillboard(createBillboardTexture(name)); 
							g.setTranslationLLA(tmp);
							locations.set(i, g);
							Log.d("NAME", "location: "+locations.get(i).getName());
							//locations.get(i)
							mRadar.add(locations.get(i));
							//locations[i].delete();
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			});
			//mSurfaceView.refreshDrawableState();
		}
		//Log.d("RETURN", "new location added, "+locations[i].toString());
		//mRadar.add(locations[i]);
		// add geometries to the radar
		//			brdgrp.addBillboard(mGeometryEast);
		//		brdgrp.addBillboard(mGeometrySouth);
		//	brdgrp.addBillboard(mGeometryNorth);
	}
	//for (IGeometry i : locations) {
	//	mRadar.add(i);
	//}
	//mRadar.add(mGeometryNorth);
	//mRadar.add(mGeometrySouth);
	//mRadar.add(mGeometryEast);


	/*
		if (mGeometrySouth != null)
		{

			//	location.setLatitude(location.getLatitude()-OFFSET);
			//	MetaioDebug.log("geometrySouth.setTranslationLLA: "+location);
			//	mGeometrySouth.setTranslationLLA(location);
			//	location.setLatitude(location.getLatitude()+OFFSET);

			LLACoordinate grdn = new LLACoordinate(51.880883, 0.920831,0, 0);
			mGeometrySouth.setTranslationLLA(grdn);
			//setGeometryVisability(mGeometrySouth);
		}

		if (mGeometryNorth != null)
		{

			//	location.setLatitude(location.getLatitude()+OFFSET);
			//	MetaioDebug.log("geometryNorth.setTranslationLLA: "+location);
			//	mGeometryNorth.setTranslationLLA(location);
			//	location.setLatitude(location.getLatitude()-OFFSET);

			LLACoordinate rndAbout = new LLACoordinate(51.880263, 0.926836,0, 0);
			mGeometryNorth.setTranslationLLA(rndAbout);
			//setGeometryVisability(mGeometryNorth);
		}

		if (mGeometryEast != null)
		{

			//	location.setLongitude(location.getLongitude()-OFFSET);
			//	MetaioDebug.log("geometryWest.setTranslationLLA: "+location);
			//	mGeometryWest.setTranslationLLA(location);
			//	location.setLongitude(location.getLongitude()+OFFSET);

			LLACoordinate uni = new LLACoordinate(51.878633, 0.953435,0, 0);
			mGeometryEast.setTranslationLLA(uni);
			//setGeometryVisability(mGeometryEast);
		}*/



	@Override
	protected void onGeometryTouched(final IGeometry geometry) 
	{
		MetaioDebug.log("Geometry selected: "+geometry);

		mSurfaceView.queueEvent(new Runnable()
		{

			@Override
			public void run() 
			{
				mRadar.setObjectsDefaultTexture(AssetsManager.getAssetPath("Tutorial5/Assets5/yellow.png"));
				mRadar.setObjectTexture(geometry, AssetsManager.getAssetPath("Tutorial5/Assets5/red.png"));
			}


		});
	}

	@Override
	public void onGravitySensorChanged(float[] gravity) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onHeadingSensorChanged(float[] orientation) {
		// TODO Auto-generated method stub

	}

}
